package cloud.seri.gateway.security.oauth2

import org.junit.After
import org.junit.Assert
import org.junit.Before
import org.junit.Test

import javax.servlet.http.Cookie

/**
 * Test the [CookieCollection].
 */
class CookieCollectionTest {
    private lateinit  var cookie: Cookie
    private lateinit  var cupsCookie: Cookie
    private lateinit  var brownieCookie: Cookie

    @Before
    @Throws(Exception::class)
    fun setUp() {
        cookie = Cookie(COOKIE_NAME, COOKIE_VALUE)
        cupsCookie = Cookie("cups", "delicious")
        brownieCookie = Cookie(BROWNIE_NAME, "mmh")
    }

    @After
    @Throws(Exception::class)
    fun tearDown() {
    }

    @Test
    @Throws(Exception::class)
    fun size() {
        val cookies = CookieCollection()
        Assert.assertEquals(0, cookies.size)
        cookies.add(cookie)
        Assert.assertEquals(1, cookies.size)
    }

    @Test
    @Throws(Exception::class)
    fun isEmpty() {
        val cookies = CookieCollection()
        Assert.assertTrue(cookies.isEmpty())
        cookies.add(cookie)
        Assert.assertFalse(cookies.isEmpty())
    }

    @Test
    @Throws(Exception::class)
    fun contains() {
        val cookies = CookieCollection(cookie)
        Assert.assertTrue(cookies.contains(cookie))
        Assert.assertTrue(cookies.contains(COOKIE_NAME))
        Assert.assertFalse(cookies.contains("yuck"))
    }

    @Test
    @Throws(Exception::class)
    operator fun iterator() {
        val cookies = CookieCollection(cookie)
        val it = cookies.iterator()
        Assert.assertTrue(it.hasNext())
        Assert.assertEquals(cookie, it.next())
        Assert.assertFalse(it.hasNext())
    }

    @Test
    @Throws(Exception::class)
    fun toArray() {
        val cookies = CookieCollection(cookie)
        val array = cookies.toArray()
        Assert.assertEquals(cookies.size, array.size)
        Assert.assertEquals(cookie, array[0])
    }

    @Test
    @Throws(Exception::class)
    fun toArray1() {
        val cookies = CookieCollection(cookie)
        val array = cookies.toArray()
        Assert.assertEquals(cookies.size, array.size)
        Assert.assertEquals(cookie, array[0])
    }

    @Test
    @Throws(Exception::class)
    fun add() {
        val cookies = CookieCollection(cookie)
        val newCookie = Cookie(BROWNIE_NAME, "mmh")
        cookies.add(newCookie)
        Assert.assertEquals(2, cookies.size)
        Assert.assertTrue(cookies.contains(newCookie))
        Assert.assertTrue(cookies.contains(BROWNIE_NAME))
    }

    @Test
    fun addAgain() {
        val cookies = CookieCollection(cookie, brownieCookie, cupsCookie)
        val white = Cookie(COOKIE_NAME, "white")
        val modified = cookies.add(white)
        Assert.assertTrue(modified)
        Assert.assertEquals(white, cookies[COOKIE_NAME])
        Assert.assertTrue(cookies.contains(white))
        Assert.assertFalse(cookies.contains(cookie))
        Assert.assertTrue(cookies.contains(COOKIE_NAME))
    }

    @Test
    fun get() {
        val cookies = CookieCollection(cookie, brownieCookie, cupsCookie)
        val c = cookies[COOKIE_NAME]
        Assert.assertNotNull(c)
        Assert.assertEquals(cookie, c)
    }

    @Test
    @Throws(Exception::class)
    fun remove() {
        val cookies = CookieCollection(cookie, brownieCookie, cupsCookie)
        cookies.remove(cookie)
        Assert.assertEquals(2, cookies.size)
        Assert.assertFalse(cookies.contains(cookie))
        Assert.assertFalse(cookies.contains(COOKIE_NAME))
        Assert.assertTrue(cookies.contains(brownieCookie))
        Assert.assertTrue(cookies.contains(BROWNIE_NAME))
    }

    @Test
    @Throws(Exception::class)
    fun containsAll() {
        val content = listOf(cookie, brownieCookie)
        val cookies = CookieCollection(content)
        Assert.assertTrue(cookies.containsAll(content))
        Assert.assertTrue(cookies.containsAll(listOf(cookie)))
        Assert.assertFalse(cookies.containsAll(listOf(cookie, brownieCookie, cupsCookie)))
        Assert.assertTrue(cookies.containsAll(listOf(COOKIE_NAME, BROWNIE_NAME)))
    }

    @Test
    @Throws(Exception::class)
    fun addAll() {
        val cookies = CookieCollection()
        val content = listOf(cookie, brownieCookie, cupsCookie)
        val modified = cookies.addAll(content)
        Assert.assertTrue(modified)
        Assert.assertEquals(3, cookies.size)
        Assert.assertTrue(cookies.containsAll(content))
        Assert.assertFalse(cookies.addAll(emptyList()))
    }

    @Test
    @Throws(Exception::class)
    fun removeAll() {
        val cookies = CookieCollection(cookie, brownieCookie, cupsCookie)
        val modified = cookies.removeAll(listOf(brownieCookie, cupsCookie))
        Assert.assertTrue(modified)
        Assert.assertEquals(1, cookies.size)
        Assert.assertFalse(cookies.contains(brownieCookie))
        Assert.assertFalse(cookies.contains(cupsCookie))
        Assert.assertFalse(cookies.removeAll(emptyList()))
    }

    @Test
    @Throws(Exception::class)
    fun removeAllByName() {
        val cookies = CookieCollection(cookie, brownieCookie, cupsCookie)
        val modified = cookies.removeAll(listOf(COOKIE_NAME, BROWNIE_NAME))
        Assert.assertTrue(modified)
        Assert.assertEquals(1, cookies.size)
        Assert.assertFalse(cookies.contains(brownieCookie))
        Assert.assertFalse(cookies.contains(cookie))
        Assert.assertFalse(cookies.removeAll(emptyList()))
    }

    @Test
    @Throws(Exception::class)
    fun retainAll() {
        val cookies = CookieCollection(cookie, brownieCookie, cupsCookie)
        val content = listOf(cookie, brownieCookie)
        val modified = cookies.retainAll(content)
        Assert.assertTrue(modified)
        Assert.assertEquals(2, cookies.size)
        Assert.assertTrue(cookies.containsAll(content))
        Assert.assertFalse(cookies.contains(cupsCookie))
        Assert.assertFalse(cookies.retainAll(content))
    }

    @Test
    @Throws(Exception::class)
    fun clear() {
        val cookies = CookieCollection(cookie)
        cookies.clear()
        Assert.assertTrue(cookies.isEmpty())
    }

    companion object {
        const val COOKIE_NAME = "chocolate"
        const val COOKIE_VALUE = "yummy"
        const val BROWNIE_NAME = "brownie"
    }
}
